﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI;
using System.Runtime.CompilerServices;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using Microsoft.UI.Xaml;
using SkiaSharp;

namespace WhaleAccount.Models;

/// <summary>
/// 月收支汇总
/// </summary>
public class MonthRecordSummary : INotifyPropertyChanged
{
    private DateTime date;
    private double income;
    private double expense;
    private double balance;

    public DateTime Date
    {
        get => date;
        set
        {
            if (date != value)
            {
                date = value;
                OnPropertyChanged();
            }
        }
    }
    public double Income
    {
        get => income;
        set
        {
            var round = Math.Round(value, 2);
            if (income != round)
            {
                income = round;
                OnPropertyChanged();
            }
        }
    }
    public double Expense
    {
        get => expense;
        set
        {
            var round = Math.Round(value, 2);
            if (expense != round)
            {
                expense = round;
                OnPropertyChanged();
            }
        }
    }
    public double Balance
    {
        get => balance;
        set
        {
            var round = Math.Round(value, 2);
            if (balance != round)
            {
                balance = round;
                OnPropertyChanged();
            }
        }
    }
    public ObservableCollection<TypeSummary> SummaryList
    {
        get;
        private set;
    }
    public ObservableCollection<Record> Records
    {
        get; private set;
    }
    public ISeries[] Series
    {
        get; set;
    }

    public MonthRecordSummary()
    {
        SummaryList = new ObservableCollection<TypeSummary>();
        Records = new ObservableCollection<Record>();
    }

    public MonthRecordSummary(DateTime date, IEnumerable<Record> records) : this()
    {
        Date = date;
        Income = records.Where(r => r.Category == 1).Sum(r => r.Value);
        Expense = records.Where(r => r.Category == 0).Sum(r => r.Value);
        Balance = income - expense;

        var data = new Dictionary<int, double>();
        var days = DateTime.DaysInMonth(Date.Year, Date.Month);
        for (var i = 1; i <= days; i++)
        {
            data.Add(i, 0);
        }
        foreach (var record in records)
        {
            var day = record.Date.Day;
            data[day] += record.Value;
        }
        var color = (Color)Application.Current.Resources["SystemAccentColor"];
        var brushColor = new SKColor(color.R, color.G, color.B, color.A);
        Series = new ISeries[]
            {
                new LineSeries<ObservablePoint>
                {
                    Values = data.Select(d => new ObservablePoint(d.Key, d.Value)),
                    Name = "Expense",
                    DataLabelsFormatter = (point) => point.PrimaryValue.ToString("C2"),
                    DataPadding = new LiveChartsCore.Drawing.LvcPoint(0.2, 0.2),
                    Stroke = new SolidColorPaint(SKColor.Parse("#2468c3")) { StrokeThickness = 2 },
                    GeometryStroke = new SolidColorPaint(SKColor.Parse("#2468c3")) { StrokeThickness = 2 },
                    GeometrySize = 8,
                    Fill = null
                }
            };

        var summaryList = (from r in records
                           group r by r.Type into g
                           select new TypeSummary
                           {
                               Type = g.Key,
                               Value = g.Sum(r => r.Value),
                               Records = g.ToList()
                           }).OrderByDescending(s => s.Value);

        foreach (var summary in summaryList)
        {
            summary.Percent = Math.Round(summary.Value * 100 / expense, 2);
            SummaryList.Add(summary);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        // Raise the PropertyChanged event, passing the name of the property whose value has changed.
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
